#include "WithBallBehaviour.h"
#include "Common/Support/Debug.h"

#define KICKIN_DBGN DO_NOTHING

/*
 * Spravanie sa hraca s loptou
 */
void WithBallBehaviour::Behave()
{
	// Hrac s loptou ma zapnutu synchronizaciu funkcii otacia krkom s VI
	world->me->bNeckSynchronization = true;

	DATA_STORAGE.myPosition = world->me->pos;

	Player* enemyGoalie = DATA_STORAGE.GetEnemyGoalie();

// Cas, ktory caka hrac s loptou pre nabiehanie si spoluhracov
#define WAIT_TIMEOUT 30
	
//	LOG - kazda akcia musi byt zachytena, aby bolo jasne, co kedy hrac robi
/*	ofstream log1("Spravanie hraca s loptou.txt", ios::app);
	
	// [CYKLUS] Hrac c. XY
	int nSimTime = world->state->GetSimTime();
	int nPlayerNumber = world->me->GetUniform();
	log1 << endl << "[" << nSimTime << "]" << " Hrac c." << nPlayerNumber << endl;
*/	
	// Jeden z nasich zahravacich modov. Niekto z timu by mal zahrat. Nie je to tento hrac, takze sa nepokusaj kopnut loptu,
	// driblovat, atd.
	
	// <ZAHRAVACI MOD> (ZASTAVENA HRA)
	if(ShouldKickIn())
	{
		// Preskumam okolie
		if(DATA_STORAGE.scanBeforeKickOffAngle <= 360)
		{
			GetScanBehaviour()->ExamineSurroundings();
			return;
		}

		// Otocili sme sa okolo svojej osi, mali by sme mat cerstve vizualne informacie a blbych superovych hracoch,
		// ktori sa nepohybuju a hladame najvhodnejsieho spoluhraca, ktoremu nahrame.

		// <Rohovy kop>
		if(world->state->GetPlayMode() == PM_CornerKick_Our)
		{
			GetOurCornerKickBehaviour()->Behave();
			return;
		}

		// <Volny kop>
		else if(world->state->GetPlayMode() == PM_FreeKick_Our)
		{
			GetOurFreeKickBehaviour()->Behave();
			return;
		}

		// <Individualny volny kop>
		else if(world->state->GetPlayMode() == PM_IndFreeKick_Our)
		{
			GetOurIndividualFreeKickBehaviour()->Behave();
			return;
		}

		// <Vhadzovanie>
		if(world->state->GetPlayMode() == PM_KickIn_Our)
		{
			GetOurKickInBehaviour()->Behave();
			return;
		}

		//zahravanie
		// <Vykopavanie> - pociatocne zahravanie zo stredu ihriska (Kick-off) alebo ak dostaneme gol
		if((world->state->GetPlayMode() == PM_KickOff_Our) || (world->state->GetPlayMode() == PM_AfterGoal_Their))
		{			
			GetOurKickOffBehaviour()->Behave();
			return;
		}

		// <Pokutovy kop>
		if(world->state->GetPlayMode() == PM_PenaltyKick_Our)
		{
			GetKickToGoalBehaviour()->Behave();
			return;
		}
	}

	// <HERNY MOD> (HRA SA)
	else
	{
		GetPlayOnWithBallBehaviour()->Behave();
	}	
}

/*
 * 
 * @return Ci ma dany hrac s loptou zahravat
 */
bool WithBallBehaviour::ShouldKickIn()
{
	bool should = DATA_STORAGE.ShouldKickIn();
	
	if(!should)
		return false;

	if(DATA_STORAGE.IsBallKickable())
		return true;

	// Najdi hraca, ktoreho domovska pozicia je najblizsie k lopte
	float distance = 100000;	// velke cislo
	int uniform;

	DATA_STORAGE.formation.SetSide(SIDE_LEFT);
	for(int i = 1; i < 12; i++)
		if((PlayerRole) DATA_STORAGE.formation.GetPlayerRole(/*SIDE_LEFT,*/ i - 1) != PR_Goalie)
		{
			Point pos = DATA_STORAGE.formation.GetPlayerPosition(i, world->ball->pos);
		
			float d = (pos - world->ball->pos).GetLength();
			
			if(d < distance)
			{
				distance = d; uniform = i;
			}
		}

	KICKIN_DBGN("%i: Number %i will kick in the ball", world->state->GetSimTime(), uniform);

	Point pos = DATA_STORAGE.formation.GetPlayerPosition(world->me->GetUniform(), world->ball->pos);
	
	if(fabsf((pos - world->ball->pos).GetLength() - distance) < 3.f)
		KICKIN_DBGN("%i: I am going to kick in", world->state->GetSimTime());
	else
		should = false;

	return should;
}
